ReflectLevel.prototype = new Sprite();

function ReflectLevel(type){
    this.name = "levelOptic";
    this.picturePath = Game.picturesPath + "levels/"+this.name + "/";
    Sprite.apply(this); 
    Level.apply(this);
    this.requiredTime = 30;
    this.type = type;
    
    //properties
    this.debug = false;
    this.laser = null;
    this.laserDraw = null;
    this.goal = null;
    this.goalMask = null;
    this.selectedMirror = null;
    this.mirrors = new Array();
    this.sockPoints = new Array();
    this.solved = false;
    this.clickedXY = new Point(0,0);
    this.manual = new Manual(this.picturePath);
    //methods assiciation
    
    this.init = LevelInit;
    this.drawLaser = drawLaser;
    this.getIndexOf = getIndexOf;
    this.isSolved = isSolved;
    
    
    function LevelInit (){
        this.laser = Game._game.bitmaps[this.picturePath+"laser.png"];
        this.laser.y = MainContainerHeight/2-20;
        this.addChild(this.laser);
    
        this.goal = Game._game.bitmaps[this.picturePath+"goal.png"];
        this.goal.x = MainContainerWidth - 40;
        this.goal.y = MainContainerHeight/2 - 20;
        this.addChild(this.goal);
    
        this.goalMask = Game._game.bitmaps[this.picturePath+"goalmask.png"];
        this.goalMask.x = MainContainerWidth - 40;
        this.goalMask.y = MainContainerHeight/2 - 20;
    
        var center = new Point(MainContainerWidth/2,MainContainerHeight/2);
    
        for (var i = 0; i < 6; i++){
            var initPoint = new Point (-150,0);
            var v = Geometry.rotate(initPoint,-60*i);
            this.sockPoints[i] = Geometry.vectorAddition(v,center);
        }
    
        var beamPath = [[new Point (20,MainContainerHeight/2),this.sockPoints[0],this.sockPoints[2]],
        [this.sockPoints[2],this.sockPoints[1],this.sockPoints[3]],
        [this.sockPoints[0],this.sockPoints[2],this.sockPoints[1]],
        [this.sockPoints[1],this.sockPoints[3],this.sockPoints[4]],
        [this.sockPoints[3],this.sockPoints[4],this.sockPoints[5]],
        [this.sockPoints[4],this.sockPoints[5],new Point (MainContainerWidth - 20,MainContainerHeight/2)]];
    
        for (i = 0; i<6; i++){
            var vecU = Geometry.pointsToVector(beamPath[i][1], beamPath[i][0]);
            var vecV = Geometry.pointsToVector(beamPath[i][1], beamPath[i][2]);
            var beamAngle = Geometry.vectorAngle(vecV,vecU);
            var nVect = Geometry.vectorAddition(Geometry.unitVector(vecU),Geometry.unitVector(vecV));
            this.mirrors[i] = new Mirror(this.sockPoints[i].x,this.sockPoints[i].y,nVect,i,this.picturePath);
            this.mirrors[i].init();
            this.mirrors[i].addEventListener(MouseEvent.CLICK,mouseClick);
            this.mirrors[i].addEventListener(MouseEvent.MOUSE_OVER,mouseOver);
            this.mirrors[i].addEventListener(MouseEvent.MOUSE_OUT,mouseOut);
            this.addChild(this.mirrors[i]);
        }
    
        for (i = 0; i<30; i++){
            var rand1 = Math.floor(Math.random()*6);
            var rand2 = Math.floor(Math.random()*6);
            switchMirrors(this, rand1, rand2);
        }
        this.laserDraw = new Sprite();
        this.addChild (this.laserDraw);
        this.drawLaser();
    
        this.addChild(this.goalMask);
        this.addChild(this.manual);
    }

    function isSolved (){
        var result = 0;
        for (var i = 0; i < 6;i++){
            result += this.mirrors[i].id*Math.pow(10,i);
        }   
        if (result == 543210 || result == 542310){
            this.timer.TimerStop();
            return true;
        }    
    
        return false;
    }

    function getIndexOf (mirror){
        for (var i = 0; i < 6; i++){
            if (this.mirrors[i] == mirror)
                return i;
        }
        return -1;
    }

    function drawLaser (){
        this.laserDraw.graphics.clear();
        var from = new Point(20,MainContainerHeight/2);
        this.laserDraw.graphics.lineStyle(2,0xff0000);
        this.laserDraw.graphics.moveTo (from.x,from.y);
        var lineLaser = new Line(from, new Point (0,1),null);
        var lineMirror;
        var currMirror = null;
        var usedMirrors = new Array();
        do{
            currMirror = null; 
            for (var i = 0; i < 6;i++){
                var mirrorI =this.mirrors[i]
            
                if (usedMirrors.indexOf(mirrorI) != -1 )
                    continue;
                if (usedMirrors.length > 0){
                    var lastMirrorLine = new Line (new Point(usedMirrors[usedMirrors.length-1].x,usedMirrors[usedMirrors.length-1].y),usedMirrors[usedMirrors.length-1].nVect);
                    if ((lastMirrorLine.a*mirrorI.x+lastMirrorLine.b*mirrorI.y+lastMirrorLine.c)<0)
                        continue;
                }
                lineMirror = new Line (new Point(mirrorI.x,mirrorI.y),mirrorI.nVect);
                var intersection = Geometry.intersectionPoint(lineLaser, lineMirror);
                if (intersection != null && Geometry.layAmong(intersection, mirrorI.getEdges()[0], mirrorI.getEdges()[1])){
                    currMirror = mirrorI;
                    usedMirrors.push(mirrorI);
                    break;
                }
            }
            if (currMirror != null){
                from = currMirror.nVect;
                this.laserDraw.graphics.lineTo(intersection.x,intersection.y);
                if (Geometry.scalarProduct(from, new Point(-lineLaser.b,lineLaser.a))<= 0){    
                    break;
                }
                lineLaser = new Line (new Point(currMirror.x,currMirror.y),Geometry.getAxiallySymmetricVector(new Point(lineLaser.a,lineLaser.b),currMirror.nVect),null);
            }
            else{
                var boundingLines = [new Line(new Point (0,0),new Point(0,1),null),
                new Line(new Point (0,0),new Point(1,0),null),
                new Line (new Point (MainContainerWidth,MainContainerHeight),new Point(0,1),null),
                new Line (new Point (MainContainerWidth,MainContainerHeight),new Point(1,0),null)];
                var boundsOfLines = [[new Point(0,0),new Point(MainContainerWidth,0)],
                [new Point(0,0),new Point(0,MainContainerHeight)],
                [new Point(MainContainerWidth,MainContainerHeight),new Point(0,MainContainerHeight)],
                [new Point(MainContainerWidth,MainContainerHeight),new Point(MainContainerWidth,0)]];                            
                var inter1 = null;
                var inter2 = null;
                for (var j = 0;j < 4;j++){
                    var intersection = Geometry.intersectionPoint(lineLaser, boundingLines[j]);
                    if (intersection != null && Geometry.layAmong(intersection, boundsOfLines[j][0], boundsOfLines[j][1])){
                        if (inter1 == null)
                            inter1 = intersection;
                        else
                            inter2 = intersection;
                    }
                }    
                if (this.debug){
                    this.laserDraw.graphics.moveTo(inter1.x, inter1.y);
                    this.laserDraw.graphics.lineTo(inter2.x, inter2.y);    
                }
                else{
                    var vectToInter = Geometry.pointsToVector(new Point(usedMirrors[usedMirrors.length-1].x,usedMirrors[usedMirrors.length-1].y),inter1);
                    if (Geometry.scalarProduct(from, vectToInter)> 0){
                        this.laserDraw.graphics.lineTo(inter1.x, inter1.y);    
                    }
                    else{
                        this.laserDraw.graphics.lineTo(inter2.x, inter2.y);    
                    }
                }
            }
        }
        while (currMirror != null)
        if (this.debug){  
            for (var i = 0;i <6;i++){
                //  normala
                this.laserDraw.graphics.lineStyle(2,0xff);
                this.laserDraw.graphics.moveTo (this.sockPoints[i].x,this.sockPoints[i].y);
                this.laserDraw.graphics.lineTo(this.sockPoints[i].x+this.mirrors[i].nVect.x*100,
                    this.sockPoints[i].y+this.mirrors[i].nVect.y*100);
                // smerova priamka laseru
                this.laserDraw.graphics.lineStyle(2,0x0);
                var boundingLines = [new Line(new Point (0,0),new Point(0,1),null),
                new Line(new Point (0,0),new Point(1,0),null),
                new Line (new Point (MainContainerWidth,MainContainerHeight),new Point(0,1),null),
                new Line (new Point (MainContainerWidth,MainContainerHeight),new Point(1,0),null)];
                var boundsOfLines = [[new Point(0,0),new Point(MainContainerWidth,0)],
                [new Point(0,0),new Point(0,MainContainerHeight)],
                [new Point(MainContainerWidth,MainContainerHeight),new Point(0,MainContainerHeight)],
                [new Point(MainContainerWidth,MainContainerHeight),new Point(MainContainerWidth,0)]];
          
                var inter1 = null;
                var inter2 = null;
                var lineMirror = new Line (new Point(this.mirrors[i].x,this.mirrors[i].y),this.mirrors[i].nVect);
                for (var j = 0;j < 4;j++){
                    var intersection = Geometry.intersectionPoint(lineMirror, boundingLines[j]);
                    if (intersection != null && Geometry.layAmong(intersection, boundsOfLines[j][0], boundsOfLines[j][1])){
                        if (inter1 == null)
                            inter1 = intersection;
                        else
                            inter2 = intersection;
                    }
                }
                this.laserDraw.graphics.moveTo(inter1.x, inter1.y);
                this.laserDraw.graphics.lineTo(inter2.x, inter2.y);    
            }
        }
    }



    function mouseClick (event){
        var owner = event.target.parent;
        if (owner.selectedMirror == null){
            owner.selectedMirror = event.target;
            event.target.graphics.lineStyle(2,0xff);
            event.target.graphics.moveTo(-20, -20);
            event.target.graphics.lineTo(-20, 20);
            event.target.graphics.lineTo(20, 20);
            event.target.graphics.lineTo(20, -20);
            event.target.graphics.lineTo(-20, -20);   
        }
        else if (owner.selectedMirror == event.target)
        {
            owner.selectedMirror = null;
            event.target.graphics.clear();
        }
        else{
            var I1 = owner.getIndexOf (owner.selectedMirror);
            var I2 = owner.getIndexOf (event.target);
            switchMirrors(owner, I1, I2);
            owner.selectedMirror = null;
            owner.drawLaser();
        }
        if (owner.isSolved()){
            owner.levelSolved();
        //alert ('gratulujem!!');
        }
    }

    function mouseOver (event){
        event.target.graphics.lineStyle(2,0x00ff00);
        event.target.graphics.moveTo(-20, -20);
        event.target.graphics.lineTo(-20, 20);
        event.target.graphics.lineTo(20, 20);
        event.target.graphics.lineTo(20, -20);
        event.target.graphics.lineTo(-20, -20);
    }

    function mouseOut (event){
        var owner = event.target.parent;
        if (event.target != owner.selectedMirror){
            event.target.graphics.clear();
        }else{
            event.target.graphics.lineStyle(2,0xff);
            event.target.graphics.moveTo(-20, -20);
            event.target.graphics.lineTo(-20, 20);
            event.target.graphics.lineTo(20, 20);
            event.target.graphics.lineTo(20, -20);
            event.target.graphics.lineTo(-20, -20);   
        }
    }

    function switchMirrors(owner,m1,m2){
        if (m1 == m2){
            return;
        }    
        var hlp = owner.mirrors[m1];
        owner.mirrors[m1] = owner.mirrors[m2];
        owner.mirrors[m2] = hlp;
        
        owner.mirrors[m1].x = owner.mirrors[m1].x ^ owner.mirrors[m2].x;
        owner.mirrors[m2].x = owner.mirrors[m1].x ^ owner.mirrors[m2].x;
        owner.mirrors[m1].x = owner.mirrors[m1].x ^ owner.mirrors[m2].x;
        
        owner.mirrors[m1].y = owner.mirrors[m1].y ^ owner.mirrors[m2].y;
        owner.mirrors[m2].y = owner.mirrors[m1].y ^ owner.mirrors[m2].y;
        owner.mirrors[m1].y = owner.mirrors[m1].y ^ owner.mirrors[m2].y;
    }

}
